#ifndef __SLAMPROCESS_H__
#define __SLAMPROCESS_H__
#include "../include/Typedef.hpp"
#include <thread>
#include <ctime>
#include "../include/Frame.hpp"
#include "../include/ORBFeature.hpp"
#include "../include/Matcher.hpp"
#include "../include/Track.hpp"
#include "../include/Param.hpp"
#include "../include/Frame.hpp"
#include "../include/Map.hpp"
#include "../include/MapAtlas.hpp"
#include "../include/MapPoint.hpp"
#include "../include/Optimizer.hpp"
#include "../include/LocalMap.hpp"
#include "../include/LoopClosing.hpp"
#include <DBoW3/DBoW3.h>
#include "../include/Converter.hpp"
#include "../include/MapAtlas.hpp"
#include "../include/Debuger.hpp"
// #include "../include/Viewer.hpp"
#include "../include/KeyFrameDatabase.hpp"
#include "../include/Imu.hpp"
using namespace std;
using namespace cv;
namespace ORBSLAM
{
    class Optimizer;
    class ImuDataPoint;
    class SlamProcess
    {
    public:
        enum e_tracking_state
        {
            NOT_INITIALIZED = 1,
            OK = 2,
            LOST = 3,
            NO_IMAGE = 4
        };

    private:
        /* data */
        ORBFeature *mp_orbfeature;
        Matcher *mp_matcher;
        Track *mp_tracker;
        Param *mp_param;
        // Map *mp_map;
        MapAtlas *mp_mapatlas;
        LocalMap *mp_localmap;
        LoopClosing *mp_loopclosing;
        // Viewer *mp_viewer;
        KeyFrameDatabase *mp_keyframedatabase;

        unique_ptr<PreIntegrater>  mp_preintegrater;
        // shared_ptr<PreIntegrater>  mp_preintegrater_lastframe;
        // PreIntegrater * mp_preintegrater_lastkeyframe;

        PreIntegrationData m_preintegrationdata_lastframe;
        PreIntegrationData m_preintegrationdata_lastkeyframe;


        thread *mpt_localmapping;
        // thread *mpt_viewer;
        thread *mpt_loopclosing;

        DBoW3::Vocabulary *mp_vocabulary;

        bool mb_mono_initialized;
        bool mb_initial_frame_ready;
        Frame mF_last_frame;
        Frame mF_curframe;
        Frame mF_initial_frame;
        vector<Point2f> mvp_prematched;
        vector<int> mvi_initial_matches;
        vector<Point3f> mvp3f_initial3d;
        vector<KeyFrame *> mvp_keyframe;
        e_tracking_state me_state;
        KeyFrame *mp_ref_KF;
        Mat mm_velocity;

        Map *mp_cur_map;

        unsigned long mn_last_relocalization_frame_id;
        int mn_para_maxkeyframe_th;
        int mn_para_minkeyframe_th;

        int mn_match_inline;

        unsigned long mn_last_keyframe_frame_id;

        int mn_init_id;
        int mn_last_id;

        // Mat im1, im2;

        KeyFrame *mp_last_keyframe;

        list<Mat> mlm_relative_frame_pose;
        list<KeyFrame *> mlp_reference_keyframe;

    public:
        SlamProcess(/* args */);

        void Process(const Mat &im,double time_stamp,vector<ImuDataPoint> v_imu_data);
        void Create_momo_initial_map();
        void Reset_active_map();
        void Compute_bow(KeyFrame *pkf);
        void Compute_bow(Frame &frame);
        bool Need_new_keyframe();
        void Create_new_keyframe();
        void Update_last_frame();
    };

}
#endif // __SLAMPROCESS_H__